#include "scene.h"

Mesh cube_mesh;
GLuint cube_list;
GLuint texture[3];

static GLfloat cubecol[5][3] =
{
    { 1.0f, 0.0f, 0.0f },
    { 1.0f, 0.5f, 0.0f },
    { 1.0f, 1.0f, 0.0f },
    { 0.0f, 1.0f, 0.0f },
    { 0.0f, 1.0f, 1.0f }
};

int build_list()
{
    /*    printf("build_list()\n"); */

    cube_list = glGenLists(1);

    glNewList(cube_list, GL_COMPILE);
    draw_mesh(&cube_mesh);
    glEndList();

    return 1;
}

int init_scene(Screen *pScreen)
{
    /*    printf("init_scene()\n"); */

    GLfloat lightAmbient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    GLfloat lightDiffuse[] = { 0.2f, 0.2f, 0.2f, 1.0f };
    GLfloat lightPosition[] = { 20.0f, 20.0f, -10.0f, 1.0f };
    GLfloat lightDirection[] = { -1.0f, 0.0f, 1.0f, 1.0f };

    if (!mesh_make_cube(&cube_mesh, 1))
    {
        fprintf(stderr, "Could not initiate scene\n");
        return 0;
    }

    build_list();

    if (!load_texture("data/crate.bmp", &texture[0], 0))
    {
        fprintf(stderr, "Could not initiate scene\n");
        return 0;
    }
    if (!load_texture("data/crate.bmp", &texture[1], 1))
    {
        fprintf(stderr, "Could not initiate scene\n");
        return 0;
    }
    if (!load_texture("data/crate.bmp", &texture[2], 2))
    {
        fprintf(stderr, "Could not initiate scene\n");
        return 0;
    }

    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
    glLightfv(GL_LIGHT0, GL_POSITION, lightDirection);
    glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 180.f);
    glEnable(GL_LIGHT0);

    glEnable(GL_LIGHTING);
    glEnable(GL_COLOR_MATERIAL);

    glViewport(0, 0, pScreen->mWidth, pScreen->mHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, pScreen->mWidth / (float)pScreen->mHeight, 1.0, 1024.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    return 1;
}

int deinit_scene()
{
    /*    printf("deinit_scene()\n"); */

    mesh_free(&cube_mesh);
    return 1;
}

int draw_scene(int mode)
{
    GLuint xloop;
    GLuint yloop;

    static GLfloat xrot = 0.0;
    static GLfloat yrot = 0.0;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    for (yloop = 1; yloop < 6; yloop++)
        for (xloop = 0; xloop < yloop; xloop++)
        {
            glLoadIdentity();
            glTranslatef(1.4f + ((float)xloop * 2.8f) - ((float)yloop * 1.4f), ((6.0f - (float)yloop) * 2.4f) - 7.0f, -14.0f);
            glRotatef(45.0f - (2.0f * yloop) + xrot, 1.0f, 0.0f, 0.0f);
            glRotatef(45.0f + yrot, 0.0f, 1.0f, 0.0f);
            glColor3fv(cubecol[yloop - 1]);

            switch (mode)
            {
            case 0:
                glDisable(GL_TEXTURE_2D);
                draw_mesh(&cube_mesh);
                break;
            case 1:
                glDisable(GL_TEXTURE_2D);
                glCallList(cube_list);
                break;
            case 2:
                glDisable(GL_TEXTURE_2D);

                glEnableClientState(GL_VERTEX_ARRAY);
                glEnableClientState(GL_NORMAL_ARRAY);

                glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &cube_mesh.vertex[0].x);
                glNormalPointer(GL_FLOAT, sizeof(Vertex), &cube_mesh.vertex[0].nx);
                glDrawArrays(GL_QUADS, 0, cube_mesh.vertex_qty);

                glDisableClientState(GL_VERTEX_ARRAY);
                glDisableClientState(GL_NORMAL_ARRAY);
                break;
            case 3:
                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, texture[0]);
                glCallList(cube_list);
                break;
            case 4:
                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, texture[1]);
                glCallList(cube_list);
                break;
            case 5:
                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, texture[2]);
                glCallList(cube_list);
                break;
            }
        }

    xrot += 0.1f;
    yrot += 0.1f;

    return 1;
}
